package jmind.core.http;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.Cookie;

import jmind.core.lang.Pair;
import jmind.core.util.DataUtil;
import jmind.core.util.GlobalConstants;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

/**
 * apache httpclient4  和3的区别比较大
 * @author xieweibo
 * @date 2015年7月10日
 */
public class HttpClient4 extends HttpClient {

    /**
     * 
     * @param url
     * @param code 编码默认 UTF-8
     * @param soTimeout 超时时间
     * @return
     */
    public String get(String url, final String code, int soTimeout) {
        long start = System.currentTimeMillis();
        CloseableHttpClient httpclient;
        String res = null;
        if (soTimeout > 0) {

            //               RequestConfig defaultRequestConfig = RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(5000)
            //                       .setConnectionRequestTimeout(5000).setStaleConnectionCheckEnabled(true).build();
            /**
             * setSocketTimeout  读出超时
             * setConnectTimeout 链接超时
             * 
             */
            RequestConfig defaultRequestConfig = RequestConfig.custom().setSocketTimeout(soTimeout).build();
            httpclient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();
        } else {
            httpclient = HttpClients.createDefault();
        }

        try {
            HttpGet httpget = new HttpGet(url);
            // Create a custom response handler
            ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
                public String handleResponse(final HttpResponse response) throws ClientProtocolException, IOException {
                    int status = response.getStatusLine().getStatusCode();
                    if (status >= 200 && status < 300) {
                        HttpEntity entity = response.getEntity();
                        return entity != null ? EntityUtils.toString(entity, code) : null;
                    } else {
                        throw new ClientProtocolException("Unexpected response status: " + status);
                    }
                }

            };
            res = httpclient.execute(httpget, responseHandler);
            statsCounter.mustGet(getURI(url)).recordSuccess(start);
            log(start, url, res);
        } catch (Exception e) {
            logger.error(url, e);
            statsCounter.mustGet(getURI(url)).recordException(start);
        } finally {
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return res;
    }

    public String get(String url, Cookie[] cookies) {
        long start = System.currentTimeMillis();
        final StringBuilder c = new StringBuilder();
        for (Cookie cookie : cookies) {
            c.append(cookie.getName()).append("=").append(cookie.getValue()).append(";");
        }
        List<BasicHeader> defaultHeaders = new ArrayList<BasicHeader>();
        defaultHeaders.add(new BasicHeader("User-Agent",
                "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0"));
        //    defaultHeaders.add(new BasicHeader("Referer", "http://www.lemall.com/heise919/miaosha.html"));
        // String cookie = "cookie_TJ_2=1432008129001_14315683642592357364_14320080188569900021_0_1; cookie_PAGE_2=7929514c651213bb29542a71e940fc02; Hm_lvt_31e53755c4dd5dd23af271aa5f6bd6b8=1441943079,1442368520,1442373363; pgv_pvi=1347116032; __xsptplus104=104.9.1442403482.1442403482.1%233%7Cwww.letv.com%7C%7C%7C%7C%23%23zwhyDQcto03-ddxsz8Kb-zvgYJg9pAQ9%23; _jzqa=1.129508388641425820.1432003066.1432003066.1442373509.2; _jzqx=1.1432003066.1442373509.2.jzqsr=letv%2Ecom|jzqct=/.jzqsr=lemall%2Ecom|jzqct=/rushfailinfo%2Ehtml-j-miaosha919%2Ehtml; COOKIE_CHECK_TIME=1442403482594; COOKIE_TOKEN_ID_N=3323feb23dd57f231dd611e82a8f1c17; COOKIE_USER_IP=10.58.89.22; COOKIE_USER_NAME=cd4433865e9f055d6e42835a7b258177; COOKIE_NICKNAME=%E9%9F%A6%E5%8D%9A___857; COOKIE_USER_LEVEL_ID=1; COOKIE_SESSION_ID=3C42254315FEADB79BB7E6306630C3E4; COOKIE_TOKEN_ID=b507bec6c807d552db73f541ca283fcb; COOKIE_TOKEN_DATE=1442401138054; COOKIE_USER_ID=2130673987; COOKIE_USER_TYPE=1; COOKIE_LOGIN_TYPE=5; COOKIE_USER_INFO=%E9%9F%A6%E5%8D%9A___857%5E%5E%5E130673987%5Ehttp%3A%2F%2Fi1.letvimg.com%2Fimg%2F201207%2F30%2Ftx298.png%2Chttp%3A%2F%2Fi0.letvimg.com%2Fimg%2F201207%2F30%2Ftx200.png%2Chttp%3A%2F%2Fi0.letvimg.com%2Fimg%2F201207%2F30%2Ftx70.png%2Chttp%3A%2F%2Fi3.letvimg.com%2Fimg%2F201207%2F30%2Ftx50.png%5E; COOKIE_USER_CITY=; COOKIE_THIRDPARTY_ID=130673987; tj_lc=b336c39cf3710e00eb86a2f971d7163b; Hm_lpvt_31e53755c4dd5dd23af271aa5f6bd6b8=1442403481; webtrekk_cookie_record=1; pgv_si=s2827873280; _jzqc=1; _jzqckmp=1; _uuid=633f8c89-0bb4-467d-9ee7-6612f0ba6013; _qzja=1.2005032643.1432003066188.1432003066188.1442373511223.1442374220334.1442375165020.0.0.0.6.2; _qzjc=1; _qzjto=4.1.0";
        defaultHeaders.add(new BasicHeader("Cookie", c.toString()));
        CloseableHttpClient httpclient = HttpClients.custom().setDefaultHeaders(defaultHeaders).build();

        String res = null;
        try {
            HttpGet httpget = new HttpGet(url);
            // Create a custom response handler
            ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
                public String handleResponse(final HttpResponse response) throws ClientProtocolException, IOException {
                    int status = response.getStatusLine().getStatusCode();
                    if (status >= 200 && status < 300) {
                        HttpEntity entity = response.getEntity();
                        return entity != null ? EntityUtils.toString(entity, GlobalConstants.ENCODE) : null;
                    } else {
                        throw new ClientProtocolException("Unexpected response status: " + status);
                    }
                }

            };
            res = httpclient.execute(httpget, responseHandler);
            log(start, url, res);
        } catch (Exception e) {
            logger.error(url, e);
        } finally {
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return res;
    }

    private String post(String url, String code, int timeout, List<NameValuePair> params) {
        long start = System.currentTimeMillis();
        CloseableHttpClient httpclient;
        if (timeout > 0) {
            RequestConfig defaultRequestConfig = RequestConfig.custom().setSocketTimeout(timeout).build();
            httpclient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();
        } else {
            httpclient = HttpClients.createDefault();
        }
        String res = null;
        CloseableHttpResponse response = null;
        try {
            HttpPost httpPost = new HttpPost(url);
            if (params != null)
                httpPost.setEntity(new UrlEncodedFormEntity(params, code));
            response = httpclient.execute(httpPost);
            HttpEntity entity2 = response.getEntity();
            res = EntityUtils.toString(entity2, code);
            EntityUtils.consume(entity2);
            statsCounter.mustGet(getURI(url)).recordSuccess(start);
            log(start, url, res);
        } catch (Exception e) {
            logger.error(url, e);
            statsCounter.mustGet(getURI(url)).recordException(start);
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                }
            }
            try {
                httpclient.close();
            } catch (IOException e) {
            }

        }
        return res;
    }

    public String post(String url, Map<String, ?> params, String code, int timeout) {
        List<NameValuePair> nvps = null;
        if (!DataUtil.isEmpty(params)) {
            nvps = new ArrayList<NameValuePair>();
            for (Entry<String, ?> entry : params.entrySet()) {
                nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
            }
        }
        return this.post(url, code, timeout, nvps);
    }

    /**
     * 
     * @param url
     * @param params 参数不用map 是因为参数名可能重复
     * @return
     * @throws java.io.IOException
     */
    public String post(String url, List<Pair<String, String>> params, String code, int timeout) {
        List<NameValuePair> nvps = null;
        if (!DataUtil.isEmpty(params)) {
            nvps = new ArrayList<NameValuePair>();
            for (Pair<String, String> entry : params) {
                nvps.add(new BasicNameValuePair(entry.first, entry.second));
            }
        }
        return this.post(url, code, timeout, nvps);

    }

    /**
     * 上传文件
     * http://blog.csdn.net/x931100537/article/details/39295221
     * @param url 请求url
     * @param params 参数
     * @param fileName file参数名
     * @param file 文件
     * @return
     */
    public String postFile(String url, Map<String, ?> params, String fileName, File file, String code) {
        Charset charset = DataUtil.isEmpty(code) ? Charset.defaultCharset() : Charset.forName(code);
        long start = System.currentTimeMillis();
        CloseableHttpClient httpclient = HttpClients.createDefault();
        String res = null;
        try {
            HttpPost httppost = new HttpPost(url);

            //  setMode 解决文件名是中文。乱码问题
            MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create()
                    .setMode(HttpMultipartMode.BROWSER_COMPATIBLE).setCharset(charset);
            multipartEntityBuilder.addBinaryBody(fileName, file);

            //           FileBody bin = new FileBody(file, ContentType.create("application/octet-stream", Consts.UTF_8),  file.getName());
            //           multipartEntityBuilder.addPart(fileName, bin);

            if (!DataUtil.isEmpty(params)) {
                ContentType contentType = ContentType.create("text/plain", charset);
                for (Entry<String, ?> entry : params.entrySet()) {
                    multipartEntityBuilder.addTextBody(entry.getKey(), entry.getValue().toString(), contentType);
                }
            }

            httppost.setEntity(multipartEntityBuilder.build());
            CloseableHttpResponse response = httpclient.execute(httppost);
            HttpEntity resEntity = response.getEntity();
            if (resEntity != null) {
                res = EntityUtils.toString(resEntity, charset);
            }
            statsCounter.mustGet(getURI(url)).recordSuccess(start);
            log(start, url, res);
        } catch (Exception e) {
            logger.error(url, e);
            statsCounter.mustGet(getURI(url)).recordException(start);
        } finally {
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return res;
    }

    @Override
    public String postBody(String url, String body) {
        long start = System.currentTimeMillis();
        CloseableHttpClient httpclient = HttpClients.createDefault();
        String res = null;
        try {
            HttpPost httppost = new HttpPost(url);
            if (!DataUtil.isEmpty(body)) {
                httppost.setEntity(new StringEntity(body, GlobalConstants.ENCODE));
            }
            CloseableHttpResponse response = httpclient.execute(httppost);
            HttpEntity resEntity = response.getEntity();
            if (resEntity != null) {
                res = EntityUtils.toString(resEntity, GlobalConstants.ENCODE);
            }
            statsCounter.mustGet(getURI(url)).recordSuccess(start);
            log(start, url, res);
        } catch (Exception e) {
            logger.error(url, e);
            statsCounter.mustGet(getURI(url)).recordException(start);
        } finally {
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return res;
    }

    //    
    //    for(File file:files){  
    //        PostMethod filePost = new PostMethod("this is url");  
    //        try {  
    //            String fileName ="filename";  
    //            // 组拼post数据的实体  
    //            Part[] parts = { new StringPart("userId", "userId"),  
    //                    new StringPart("fileName", URLEncoder.encode(URLEncoder.encode(fileName, "utf-8"), "utf-8")),  
    //                    new FilePart("file", file),  
    //
    //            };  
    //            filePost.setRequestEntity(new MultipartRequestEntity(parts,filePost.getParams()));  
    //            HttpClient client = new HttpClient();  
    //            client.getHttpConnectionManager().getParams().setConnectionTimeout(5000);  
    //            // 执行文件上传的post请求  
    //            client.executeMethod(filePost);  
    //
    //        } catch (Exception e) {  
    //            e.printStackTrace();  
    //
    //        } finally {  
    //            filePost.releaseConnection();  
    //        }  
    //    }  

}
